
Ext.Loader.setConfig({enabled: true});
Ext.Loader.setPath('Ext.ux.DataView', '../ux/DataView/');

Ext.require([
    'Ext.data.*',
    'Ext.util.*',
    'Ext.view.View',
    'Ext.ux.DataView.Animated',
    'Ext.XTemplate',
    'Ext.panel.Panel',
    'Ext.toolbar.*',
    'Ext.slider.Multi'
]);

Ext.onReady(function() {


    /**
     * MODELS
     */



    // Model to represent presidential terms
    Ext.define('Terms', {
        extend: 'Ext.data.Model',
        fields: [
            'from', 'to'
        ]

    });


    // Model to represent presidents
    Ext.define('Presidents', {
        extend: 'Ext.data.Model',
        fields: [
            {name: 'id', type: 'int'},
            'first', 'last',
            {name: 'start', type: 'int'},
            {name:  'finish', type: 'int'},
            'image', 'party'
        ],

        hasMany: {
            model: 'Terms', name: 'terms'
        }
    });

    // Model to represent terms and dates
    Ext.define('Chart.PresParty', {

        extend: 'Ext.data.Model',
        fields: ['party', 'count'],
        proxy: 'memory'

    });


    // Model to represent presidential facts
    Ext.define('Facts', {

        // Fill out proper model definition- dont forget hasMany relationship

    });

    // Store to house president models
    var presidentStore = Ext.create('Ext.data.Store', {

        model: 'Presidents',
        proxy: {

            type: 'ajax',
            url: 'pres_data.json',
            reader: {
                type: 'json',
                root: 'presidents'
            }
        },
        autoLoad: true,
        listeners: {
            dataChanged: fillChartStore
        }
    });

    var chartStore = Ext.create('Ext.data.Store', {

        model: 'Chart.PresParty'
    });


    /**
     * VIEWS
     */


    // Our main template view
    var dataview = Ext.create('Ext.view.View', {
        store: presidentStore,

        tpl  : Ext.create('Ext.XTemplate',
            '<tpl for=".">',
                '<div class="president">',
                    '<img src="../images/{image}" />',
                    '<strong>{first} {last}<br />(Party: {party})</strong>',
                    '<tpl for="terms">',
                        '<p>Term {#}: {from}-{to}</p>',
                    '</tpl>',
                '</div>',
            '</tpl>'
        ),

        plugins : [
            Ext.create('Ext.ux.DataView.Animated', {
                duration: 650,
                idProperty: 'id'
            })
        ],

        id: 'presidents',
        itemSelector: 'div.president',
        overItemCls : '.president-hover',
        autoScroll  : true,

        listeners: {
            itemclick: itemclickHandler
        }
    });



    //template helpers
    var nameFilter = Ext.create('Ext.form.Text', {

        hideLabel: true,
        emptyText: 'Filter By Name',
        listeners: {
            change: filterByName
        }
    });

    var resetButton = Ext.create('Ext.Button', {

        text: 'Reset Filter',
        handler: resetFilter

    });

    var toolbar = Ext.create('Ext.toolbar.Toolbar', {

        dock: 'top',
        items: ['<a href="http://www.cs.siu.edu/~akulis/cs412-extjs/Assignment.pdf">Assignment</a>', '->', '-', nameFilter, '-', resetButton]
    });



    //chart
    var chart = Ext.create('Ext.chart.Chart', {

        width: 800,
        height: 365,
        animate: true,
        store: chartStore,
        theme: 'Category1',
        axes: [{
            type: 'Numeric',
            position: 'left',
            fields: ['count'],
            title: 'Party Count',
            minimum: 0
        },{
            type: 'Category',
            position: 'bottom',
            fields: ['party'],
            title: 'Party'
        }],
        series: [{
            type: 'column',
            highlight: true,
            label: {
                display: 'insideEnd',
                'text-anchor': 'middle',
                field: 'count'
            },
            xField: 'party',
            yField: 'count'
        }]
    });

    // Main View panel
    var dvCont = Ext.create('Ext.Container', {

        layout: 'fit',
        items : dataview,
        height: 330,
        width: 810

    });

    var chartCont = Ext.create('Ext.Container', {

        padding: '20 0 0 0',
        items: chart
    });

    // main panel
    var p = Ext.create('Ext.Panel', {

        items: [dvCont, chartCont],
        dockedItems: toolbar,
        width: 815
    });


    // Window to house the elements
    var win = Ext.create('Ext.Window', {

        title: 'United States Presidents',
        modal: true,
        closable: false,
        collapsible: false,
        draggable: false,
        resizable: false,
        items: p

    });


    var popup = Ext.create('Ext.Window', {

        //todo: place form panel here, set size, set modal, ...
    });

    /**
     * CONTROLLERS
     */
    function resetFilter(){

        //clear tf ONLY
        nameFilter.reset();

        //clear store filter
        presidentStore.clearFilter();


        //reload
        hack();
    }

    function filterByNameHelper(){


        //get query from tf and force regex to match from beginning
        var q = '^' + nameFilter.getValue();

        if(q === '^') return true;

        var rec = arguments[0];
        var fn = rec.get('first');
        var ln = rec.get('last');

        //create regex
        var regex = new RegExp(q, 'i');

        //test
        return regex.test(fn) || regex.test(ln);
    }

    function filterByName(){

        //prepare
        presidentStore.suspendEvents()
        presidentStore.clearFilter();
        presidentStore.resumeEvents();

        //filter store accordingly
        presidentStore.filter([{

            fn: filterByNameHelper

        }]);


        hack();
    }

    function fillChartStore(){

        //empty store
        chartStore.removeAll(true);

        var party = {};

        for(var i = 0; i < presidentStore.getCount(); i++){

            var rec = presidentStore.getAt(i);
            var currParty = rec.get('party');
            if(!(currParty in party)) party[currParty] = 1;
            else party[currParty]++;

        }

        for(var p in party){
            var rec = Ext.ModelMgr.create({

                party: p,
                count: party[p]

            }, 'Chart.PresParty');

            chartStore.insert(chartStore.getCount(), rec);
        }



    }

    function itemclickHandler(){
        alert('It is your job to develop a form to update presidential facts. Specs and requirements included in the handout');
    }

    function hack(){

        //sometimes plugin doesn't render properly. Uncomment to reload store as needed.
        //Causes data to be pulled from online resource, but applies filter (if any)

        //uncomment to turn on
        //presidentStore.load();
    }


    win.doLayout();
    win.show();
});